package net.ix.util;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.HttpVersion;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.CoreProtocolPNames;
import org.apache.http.util.EntityUtils;

import android.util.Log;

public class IXHttp{
	private static String tag = "IXHttp";
	private final static String UTF8 = "UTF-8";
	
	public IXHttp(){
		
	}
	
	public static final class HttpsParams {
		private final Map<String, String> parameters = new HashMap<String,String>();

		public HttpsParams() {
		}
		public synchronized Object getParameter(final String name) {
			return this.parameters.get(name);
		}
		public synchronized HttpsParams setParameter(final String name,final String value) {
			this.parameters.put(name, value);
			return this;
		}

		public boolean isEmpty() {
			return parameters.isEmpty();
		}

		public Map<String, String> getParameters() {
			return parameters;
		}
	}
	
	public static final class HttpsResponse {
		private final int responseCode;
		private final String content;

		public HttpsResponse(int responseCode, String content) {
			this.responseCode = responseCode;
			this.content = content;
		}

		public int getResponseCode() {
			return responseCode;
		}

		public String getContent() {
			return content;
		}
	}
	
	public static HttpsResponse post(URI uri,HttpsParams params) {
		HttpPost httpPost = prepareHttpPost(uri, params);
		return executeHttpMethod(httpPost);
	}
	
	private static HttpPost prepareHttpPost(URI uri, HttpsParams params) {
		HttpPost httpPost = new HttpPost(uri);
		copy2PostEntity(params, httpPost);
		return httpPost;
	}
	
	private static void copy2PostEntity(HttpsParams params, HttpPost httpPost) {
		if (!params.isEmpty()) {
			List<NameValuePair> formParams = copy2NameValuePairs(params);
			UrlEncodedFormEntity postEntity;
			try {
				postEntity = new UrlEncodedFormEntity(formParams,UTF8);
				httpPost.setEntity(postEntity);
			} catch (UnsupportedEncodingException e) {
			}
		}
	}
	
	private static List<NameValuePair> copy2NameValuePairs(HttpsParams params) {
		List<NameValuePair> queryParams = new ArrayList<NameValuePair>();

		Iterator<Entry<String, String>> iter = params.getParameters().entrySet().iterator();
		while (iter.hasNext()) {
			Map.Entry<String, String> entry = iter.next();
			queryParams.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
		}
		return queryParams;
	}
	
	private static HttpsResponse executeHttpMethod(HttpRequestBase httpMethod) {
		String content = "";
		HttpClient httpclient = new DefaultHttpClient();
		httpclient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);

		HttpResponse response;
		try {
			Log.d(tag, "executing request " + httpMethod.getRequestLine());
			response = httpclient.execute(httpMethod);
			Log.d(tag, "http status is "+ response.getStatusLine().getStatusCode());
			int statusCode = response.getStatusLine().getStatusCode();
			if (HttpStatus.SC_OK == statusCode) {
				HttpEntity entity = response.getEntity();
				if (entity != null) {
					content = EntityUtils.toString(entity, UTF8);
				}
				if (entity != null) {
					entity.consumeContent();
				}
			}
			return new HttpsResponse(statusCode, content);
		} catch (ClientProtocolException e) {
			throw new IllegalStateException("ClientProtocol Exception!", e);
		} catch (IOException e) {
			throw new IllegalArgumentException("bad uri!", e);
		} finally {
			httpclient.getConnectionManager().shutdown();
		}
	}
}